package com.atguigu.gmall.search.listener;

import com.atguigu.gmall.common.bean.ResponseVo;
import com.atguigu.gmall.pms.entity.*;
import com.atguigu.gmall.search.feign.PmsClient;
import com.atguigu.gmall.search.feign.WmsClient;
import com.atguigu.gmall.search.service.GoodsRepository;
import com.atguigu.gmall.search.vo.Goods;
import com.atguigu.gmall.search.vo.SearchAttrValue;
import com.atguigu.gmall.wms.entity.WareSkuEntity;
import com.rabbitmq.client.Channel;
import io.jsonwebtoken.lang.Collections;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.query.DeleteQuery;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Author zhaoshuo
 * @ClassName RabbitmqListener
 * @Description
 */
@Configuration
@Slf4j
public class RabbitmqListener {

    @RabbitListener(bindings = {@QueueBinding(value = @Queue(name = "gmall.goods.queue", durable = "true"),
                    exchange = @Exchange(name = "gmall.goods.exchange", durable = "true", type = ExchangeTypes.TOPIC,
                            ignoreDeclarationExceptions = "true"), key = "goods.*")})
    public void goodOperateListener(Message message, Map<String, String> map, Channel channel) {
        try {
            String operate = map.get("operate");
            if ("1".equals(operate)) {
                String spuId = map.get("spuId");
                this.saveGoods(spuId);
            } else if ("2".equals(operate)) {
                String skuId = map.get("skuId");
                goodsRepository.deleteById(Long.parseLong(skuId));
            }
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            log.error("消息消费异常：" + ExceptionUtils.getStackTrace(e));
            try {
                if (message.getMessageProperties().isRedelivered()) {
                    channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
                } else {
                    channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
                }
            } catch (IOException ex) {
            }
        }
    }

    @Autowired
    PmsClient pmsClient;
    @Autowired
    WmsClient wmsClient;
    @Autowired
    ElasticsearchRestTemplate restTemplate;
    @Autowired
    GoodsRepository goodsRepository;

    public void saveGoods(String sid) {
        Long spuId = Long.parseLong(sid);
        //根据spuId查询spu对象
        ResponseVo<SpuEntity> spuResponseVo = pmsClient.querySpuById(spuId);
        if (spuResponseVo.getCode() != 0 || spuResponseVo.getData() == null) {
            return;
        }
        SpuEntity spuEntity = spuResponseVo.getData();
        Long brandId = spuEntity.getBrandId();
        Long categoryId = spuEntity.getCategoryId();

        //3、查询每个spu的品牌：逆向工程生成的    pms  BrandController
        ResponseVo<BrandEntity> brandResponseVo = pmsClient.queryBrandById(brandId);

        //4、查询每个spu的分类： 逆向工程生成的  pms  CategoryController
        ResponseVo<CategoryEntity> categoryResponseVo = pmsClient.queryCategoryById(categoryId);

        //5、查询每个spu的检索属性和值：多表联查  需要自定义接口 pms SpuAttrValueController
        ResponseVo<List<SpuAttrValueEntity>> spuAttrsResponseVo = pmsClient.querySpuSearchAttrValues(spuId);

        //6、查询spu的所有的sku集合：接口已存在  修改接口ResponseVo响应的泛型
        ResponseVo<List<SkuEntity>> skusResponseVo = pmsClient.querySkusBySpuId(spuId + "");
        if (skusResponseVo.getCode() == 0 && !Collections.isEmpty(skusResponseVo.getData())) {
            //查询sku集合成功
            List<SkuEntity> skuEntities = skusResponseVo.getData();
            //7、遍历sku集合：
            for (SkuEntity skuEntity : skuEntities) {
                //初始化goods对象
                Goods goods = new Goods();
                Long skuId = skuEntity.getId();
                goods.setSkuId(skuId);
                if (brandResponseVo.getCode() == 0 && brandResponseVo.getData() != null) {
                    //查询品牌成功
                    BrandEntity brandEntity = brandResponseVo.getData();
                    goods.setBrandId(brandEntity.getId());
                    goods.setBrandName(brandEntity.getName());
                    goods.setLogo(brandEntity.getLogo());
                }
                if (categoryResponseVo.getCode() == 0 && categoryResponseVo.getData() != null) {
                    //查询分类成功
                    CategoryEntity categoryEntity = categoryResponseVo.getData();
                    goods.setCategoryId(categoryEntity.getId());
                    goods.setCategoryName(categoryEntity.getName());
                }
                //spu和sku的检索属性和值 都转为SearchAttrValue的对象存到一个集合中
                List<SearchAttrValue> searchAttrValues = new ArrayList<>();
                if (spuAttrsResponseVo.getCode() == 0 && !Collections.isEmpty(spuAttrsResponseVo.getData())) {
                    //查询spu检索属性和值成功
                    for (SpuAttrValueEntity spuAttrValueEntity : spuAttrsResponseVo.getData()) {
                        SearchAttrValue searchAttrValue = new SearchAttrValue();
                        searchAttrValue.setAttrId(spuAttrValueEntity.getAttrId());
                        searchAttrValue.setAttrName(spuAttrValueEntity.getAttrName());
                        searchAttrValue.setAttrValue(spuAttrValueEntity.getAttrValue());
                        searchAttrValues.add(searchAttrValue);
                    }
                }
                //8、查询sku的检索属性和值：多表联查  需要自定义接口 pms SkuAttrValueController
                ResponseVo<List<SkuAttrValueEntity>> skuAttrsResponseVo = pmsClient.querySkuSearchAttrValues(skuId);
                if (skuAttrsResponseVo.getCode() == 0 && !CollectionUtils.isEmpty(skuAttrsResponseVo.getData())) {
                    for (SkuAttrValueEntity skuAttrValueEntity : skuAttrsResponseVo.getData()) {
                        SearchAttrValue searchAttrValue = new SearchAttrValue();
                        searchAttrValue.setAttrId(skuAttrValueEntity.getAttrId());
                        searchAttrValue.setAttrName(skuAttrValueEntity.getAttrName());
                        searchAttrValue.setAttrValue(skuAttrValueEntity.getAttrValue());
                        searchAttrValues.add(searchAttrValue);
                    }
                }
                //9、查询sku的库存和销量：wms服务  接口已存在  修改接口ResponseVo响应的泛型
                ResponseVo<List<WareSkuEntity>> wareSkusResponseVo = wmsClient.queryWareSkusBySkuId(skuId + "");
                if (wareSkusResponseVo.getCode() == 0 && !CollectionUtils.isEmpty(wareSkusResponseVo.getData())) {
                    //库存销量查询成功
                    List<WareSkuEntity> wareSkuEntities = wareSkusResponseVo.getData();
                    goods.setStore(wareSkuEntities.stream().anyMatch(wareSkuEntity ->
                            wareSkuEntity.getStock() - wareSkuEntity.getStockLocked() > 0));
                    //销量存的是数值：多个仓库销量的累加
                    goods.setSales(wareSkuEntities.stream().map(wareSkuEntity -> wareSkuEntity.getSales())
                            .reduce((a, b) -> a + b).get());

                }
                //10、将每个sku需要的数据封装到Goods对象中
                goods.setSearchAttrValues(searchAttrValues);
                goods.setPrice(skuEntity.getPrice().doubleValue());
                goods.setTitle(skuEntity.getTitle());
                goods.setSubtitle(skuEntity.getSubtitle());
                goods.setCreateTime(spuEntity.getCreateTime());
                goods.setDefaultImage(StringUtils.isEmpty(skuEntity.getDefaultImage())
                        ? "https://img14.360buyimg.com/n7/jfs/t1/143843/25/21094/107919/617a971eE340d3150/b93330bcae736ceb.jpg.avif" : skuEntity.getDefaultImage());
                restTemplate.save(goods);
            }
        }
    }
}